﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using BoxSheep.controls;
using GameDataHelper;
using Image = System.Windows.Controls.Image;
using Point = System.Drawing.Point;

namespace BoxSheep
{
    /// <summary>
    /// MainGame.xaml 的交互逻辑
    /// </summary>
    public partial class MainGame : UserControl
    {
        private DispatcherTimer dispatcherTimer;
        private EventHandler UpdateEvent;
        //主角极其所在的位置的格子数
        private MainRole mainRole;
        Point rolePosition=new Point(4,5);
        //默认每格的宽高度
        private int defaultWidth = 30; 
        private int defaultHeight = 30;
        //背景图片，宽度693, 高度600
        private Image bg;
        //默认方格开始的左上角位置,应该采用坐标表示,而非格子
        Point defaultPosition=new Point(40,20);
        //地图的数组数据
        private int[,] mapArray;
        //游戏呈现的图片元素资源, 包括地图中的，以及游戏用到的
        BitmapImage[] images=new BitmapImage[5];
        //箱子所在格子数组
        private List<Point> boxPosition;
        //所有箱子的呈现所使用的图片,根据箱子所在格子变化而变换所在呈现位置
        private List<Image> boxImages;
       //要移动到得目标位置数组
        private List<Point> targetPosition;

        //关卡ID
        private int level = 0;
        //本关关卡信息
        private Level myLevel;
        private int TimeCount = 0;
        private int stepCount = 0;
        //关卡信息
        Label inforRole=new Label();
        Label inforMap=new Label();
        //格子的最大宽度和最大高度
        private int maxWidth = 10;
        private int maxHeight = 10;   
        // 0空白区域，1可通行区域，2障碍区，3是河流，
        private Border border;
        Point CompletePosition=new Point(-1,-1);
        public MainGame(int level)
        {
        // images.
            InitializeComponent();
            stepCount = 0;
            TimeCount = 0;
            myLevel = GameStateManagy.GetLevel(level);
            textBlock1.Text += level.ToString()+"\n按PageDown进入\n下一关,\nR重新开始本关,\n上下左右方向键\n移动人物和推箱子";
            this.level = level;
            mapArray = myLevel.MapArray;
            maxHeight = mapArray.GetLength(0);
            maxWidth = mapArray.GetLength(1);
            bg=new Image();
            mainArea.Children.Add(bg);
            bg.Source = new BitmapImage(new Uri(@"/BoxSheep;component/Images/back003.jpg",UriKind.Relative));
            Canvas.SetZIndex(bg,1);
            //this.AddChild(mainRole);\
 

            images[0] = new BitmapImage(new Uri(@"/BoxSheep;component/Images/grass.png", UriKind.Relative));       //草地
            images[1] = new BitmapImage(new Uri(@"/BoxSheep;component/Images/stone.png", UriKind.Relative));      //石头
            images[2] = new BitmapImage(new Uri(@"/BoxSheep;component/Images/river.png", UriKind.Relative));         //河流 
            images[3] = new BitmapImage(new Uri(@"/BoxSheep;component/Images/box.png", UriKind.Relative));         //箱子 
            images[4] = new BitmapImage(new Uri(@"/BoxSheep;component/Images/target.png", UriKind.Relative));         //目标区域 

            for (int i = 0; i < mapArray.GetLength(1); i++)
            {
                for (int j = 0; j < mapArray.GetLength(0); j++)
                {
                    switch (mapArray[j,i])
                    {
                        case 0:
                            break;
                        case 1:
                            Image grass=new Image();
                            grass.Source = images[0];
                            grass.Width = defaultWidth;
                            grass.Height = defaultHeight;
                            grass.RenderTransform=new TranslateTransform()
                                                      {
                                                          X = defaultPosition.X+i*defaultWidth,
                                                          Y = defaultPosition.Y+j*defaultHeight
                                                      };
                            mainArea.Children.Add(grass);
                            Canvas.SetZIndex(grass,2);
                            break;
                        case 2:
                            Image stone=new Image();
                            stone.Source = images[1];
                            stone.Width = defaultWidth;
                            stone.Height = defaultHeight;
                            stone.RenderTransform = new TranslateTransform()
                                                      {
                                                          X = defaultPosition.X+i*defaultWidth,
                                                          Y = defaultPosition.Y+j*defaultHeight
                                                      };
                            mainArea.Children.Add(stone);
                            Canvas.SetZIndex(stone, 2);
                       //  test = stone;
                            break;
                        case 3:
                            Image river=new Image();
                            river.Source = images[2];
                            river.Width = defaultWidth;
                            river.Height = defaultHeight;
                            river.RenderTransform = new TranslateTransform()
                                                      {
                                                          X = defaultPosition.X+i*defaultWidth,
                                                          Y = defaultPosition.Y+j*defaultHeight
                                                      };
                            mainArea.Children.Add(river);
                            Canvas.SetZIndex(river, 2);
                            break;

                      default:
                            break;
                    }
                }
            }
     boxPosition=myLevel.Boxes;
            targetPosition = myLevel.Targets;
            foreach (Point point in targetPosition)
            {
                Image targetImage = new Image();
                targetImage.Source = images[4];
                targetImage.Width = defaultWidth;
                targetImage.Height = defaultHeight;
                targetImage.RenderTransform = new TranslateTransform()
                {
                    X = point.X * defaultWidth + defaultPosition.X ,
                    Y = point.Y * defaultHeight + defaultPosition.Y
                };
                mainArea.Children.Add(targetImage);
                Canvas.SetZIndex(targetImage, 3);
            }
       
      
            boxImages=new List<Image>();
            for (int i = 0; i < boxPosition.Count(); i++)
            {
                Image image=new Image();

                image.Source = images[3];
                image.Width = defaultWidth;
                image.Height = defaultHeight;
                image.RenderTransform = new TranslateTransform()
                                                 {
                                                     X = boxPosition[i].X*defaultWidth+defaultPosition.X,
                                                     Y = boxPosition[i].Y*defaultHeight+defaultPosition.Y
                                                 };
                boxImages.Add(image);
                mainArea.Children.Add(image);
                Canvas.SetZIndex(image, 3);
            }

            rolePosition = myLevel.StartPosition;
            mainRole = new MainRole();
         //   rolePosition.X = defaultPosition.X*defaultWidth + startPosition.X*defaultWidth;
       //     rolePosition.Y = defaultPosition.Y*defaultHeight + startPosition.Y*defaultHeight;
            mainRole.RenderTransform = new TranslateTransform()
                                         {
                                             X = rolePosition.X * defaultWidth + defaultPosition.X ,
                                             Y = rolePosition.Y * defaultHeight + defaultPosition.Y 
                                         };
            mainArea.Children.Add(mainRole);
            Canvas.SetZIndex(mainRole,10);
            inforMap.RenderTransform=new TranslateTransform()
                                         {
                                             X = 700,
                                             Y = 180
                                         };
            mainArea.Children.Add(inforMap);
            Canvas.SetZIndex(inforMap, 10);
            inforRole.RenderTransform=new TranslateTransform()
                                          {
                                              X = 700,
                                              Y = 280
                                          };
            mainArea.Children.Add(inforRole);
            Canvas.SetZIndex(inforRole, 10);
            border=new Border();
            border.BorderThickness =new Thickness(4,4,4,4);
            border.BorderBrush=new SolidColorBrush(Colors.BurlyWood);
            border.Height = maxHeight * defaultHeight + 2 *border.BorderThickness.Bottom;
            border.Width = maxWidth * defaultWidth + 2 * border.BorderThickness.Bottom;
            border.RenderTransform=new TranslateTransform()
                                       {
                                           X = defaultPosition.X - border.BorderThickness.Bottom,
                                           Y = defaultPosition.Y - border.BorderThickness.Bottom
                                       };
            mainArea.Children.Add(border);
            Canvas.SetZIndex(border, 11);
       dispatcherTimer = new DispatcherTimer();
            //      dispatcherTimer.Tick += new EventHandler(update)
          UpdateEvent = new EventHandler(update);
            dispatcherTimer.Tick += UpdateEvent;
            dispatcherTimer.Interval = TimeSpan.FromMilliseconds(16);       //60帧为16毫秒间隔
            dispatcherTimer.Start();
        }
        private void update(object sender, EventArgs e)
        {
            TimeCount += 16; 
            inforMap.Content = "地图信息：\n高：" + mapArray.GetLength(0) + "\n宽:" + mapArray.GetLength(1) +
                               "箱子总数:" + boxPosition.Count();
        inforRole.Content = "人物所在信息:\n" + (int)rolePosition.Y+","+ (int)rolePosition.X+
            "总时间："+TimeCount/1000+"\n总步数:"+stepCount;
            mainRole.RenderTransform = new TranslateTransform()
            {
                X = rolePosition.X * defaultWidth + defaultPosition.X ,
                Y = rolePosition.Y * defaultHeight + defaultPosition.Y 
            };
        //    textBlock1.Text = "实际宽度：" + Math.Round(test. ,0)+ "实际高度：" +Math.Round( test.ActualHeight,0);
                           
        //    textBlock1.Background = System.Windows.Media.Brushes.Yellow;
            for (int i = 0; i < boxImages.Count(); i++)
            {
                boxImages[i].Width = defaultWidth;
                boxImages[i].Height = defaultHeight;
                boxImages[i].RenderTransform = new TranslateTransform()
                {
                    X = boxPosition[i].X * defaultWidth + defaultPosition.X ,
                    Y = boxPosition[i].Y * defaultHeight + defaultPosition.Y 
                };
            }
            if (CompletePosition == rolePosition)
            {

              //  MessageBox.Show("关卡" + level.ToString() + "完成");
               // GameStateManagy.StartGame(level + 1);
                GameEnd end = new GameEnd(level, TimeCount, stepCount);
                mainArea.Children.Add(end);
                end.RenderTransform=new TranslateTransform(150,150);
Canvas.SetZIndex(end,20);
            //    end.Width = 200;
              //  end.Height = 300;
                dispatcherTimer.IsEnabled = false;
            }
            if (CheckComplete())
            {

                CompletePosition = myLevel.ExitPosition;
                Image endImage = new Image();
                endImage.Source = new BitmapImage(new Uri(@"/BoxSheep;component/Images/endpicture.png", UriKind.Relative));
                endImage.Height = 30;
                endImage.Width = 30;
                endImage.RenderTransform = new TranslateTransform()
                {
                    X = CompletePosition.X * defaultWidth + defaultPosition.X,
                    Y = CompletePosition.Y * defaultHeight + defaultPosition.Y,
                };
                mainArea.Children.Add(endImage);
                Canvas.SetZIndex(endImage,5);
          //      dispatcherTimer.Interval = TimeSpan.FromMilliseconds(160);
                //     MessageBox.Show("关卡"+level.ToString()+"完成");
                //this.RemoveHandler( dispatcherTimer.Tick+ ,UpdateEvent);
            }
        }
        private void Repaint()
        {
            //清除所有图元
            mainArea.Children.Clear();
            //添加背景
            mainArea.Children.Add(bg);
            //添加地图元素
            for (int i = 0; i < mapArray.GetLength(1); i++)
            {
                for (int j = 0; j < mapArray.GetLength(0); j++)
                {
                    switch (mapArray[j, i])
                    {
                        case 0:

                            break;
                        case 1:
                            Image grass = new Image();
                            grass.Source = images[0];
                            grass.Width = defaultWidth;
                            grass.Height = defaultHeight;
                            grass.RenderTransform = new TranslateTransform()
                            {
                                X = defaultPosition.X + i * defaultWidth,
                                Y = defaultPosition.Y + j * defaultHeight
                            };
                            mainArea.Children.Add(grass);
                            break;
                        case 2:
                            Image stone = new Image();
                            stone.Source = images[1];
                            stone.Width = defaultWidth;
                            stone.Height = defaultHeight;
                            stone.RenderTransform = new TranslateTransform()
                            {
                                X = defaultPosition.X + i * defaultWidth,
                                Y = defaultPosition.Y + j * defaultHeight
                            };
                            mainArea.Children.Add(stone);
                            //  test = stone;
                            break;
                        case 3:
                            Image river = new Image();
                            river.Source = images[2];
                            river.Width = defaultWidth;
                            river.Height = defaultHeight;
                            river.RenderTransform = new TranslateTransform()
                            {
                                X = defaultPosition.X + i * defaultWidth,
                                Y = defaultPosition.Y + j * defaultHeight
                            };
                            mainArea.Children.Add(river);
                            break;

                        default:
                            break;
                    }
                }
            }
            //添加目标图元
            foreach (Point point in targetPosition)
            {
                Image targetImage = new Image();
                targetImage.Source = images[4];
                targetImage.Width = defaultWidth;
                targetImage.Height = defaultHeight;
                targetImage.RenderTransform = new TranslateTransform()
                {
                    X = point.X * defaultWidth + defaultPosition.X,
                    Y = point.Y * defaultHeight + defaultPosition.Y
                };
                mainArea.Children.Add(targetImage);
            }
            //添加箱子
            for (int i = 0; i < boxImages.Count(); i++)
            {

                mainArea.Children.Add(boxImages[i]);
            }
            //添加主角
            mainArea.Children.Add(mainRole);


            mainArea.Children.Add(inforMap);

            mainArea.Children.Add(inforRole);

            mainArea.Children.Add(border);
         
        }

        public void GameApp_KeyDown(object sender, KeyEventArgs e)
        {
        //    textBlock1.Text = "捕获按键活动，按下" + e.Key.ToString() + "\n";
            switch (e.Key)
            {

                    //方向键移动逻辑
                /*
                 * 分为种情况：
                 * 1.前方格子为不可通行区域
                 * 2.前方格子为可通行区域
                 * 3.有格子放在此区域
                 * ，此种情况下又分为以下几种情况：
                 * 1.格子前方可通行，
                 * 2.格子前方不可通行
                 * 3格子前方有箱子放着.
                 */
                case Key.PageDown:
                    if(GameStateManagy.levels.Count>=level+1)
                    GameStateManagy.StartGame(level+1);
                    else
                    {
                        MessageBox.Show("最后一关了!!!");
                    }
                    break;
                case Key.Right:
                 //   rolePosition.X += 1;
                    Point targetR01=new Point(rolePosition.X+1,rolePosition.Y); //  目标位置
                    Point targetR02= new Point(rolePosition.X + 2, rolePosition.Y);     //目标位置的目标位置
                    if(IsAccessable(targetR01))
                    {
                        //目标区域有箱子放置时
                        if(IsBoxOn(targetR01))
                        {
                            if(IsAccessable(targetR02)&&!IsBoxOn(targetR02))
                            {
                                MoveRole(1, 0);
                                MoveBox(targetR01,1,0);
                            }
                            else if (mapArray[(int)targetR02.Y,(int)targetR02.X]==3)
                            {
                                //将目标区域设为可通行区域,并添加可通行图片到画面中
                                MoveRole(1, 0);
                         //       mapArray[(int) targetR02.Y, (int) targetR02.X] = 1;
                                ChangeMapArray(targetR01,targetR02);
                            }
                        
                        }
                        else
                        {
                            MoveRole(1, 0);
                        }
                    }
                    else
                    {
                        
                    }
                    break;
                    case Key.Left:
                    
                      Point targetL01=new Point(rolePosition.X-1,rolePosition.Y); //  目标位置
                    Point targetL02= new Point(rolePosition.X - 2, rolePosition.Y);     //目标位置的目标位置
                    if(IsAccessable(targetL01))
                    {
                        //目标区域有箱子放置时
                        if(IsBoxOn(targetL01))
                        {
                            if(IsAccessable(targetL02)&&!IsBoxOn(targetL02))
                            {
                                MoveRole(-1, 0);
                                MoveBox(targetL01,-1,0);
                            }
                            else if (mapArray[(int)targetL02.Y, (int)targetL02.X] == 3)
                            {
                                //将目标区域设为可通行区域,并添加可通行图片到画面中
                                MoveRole(-1, 0);
                                //       mapArray[(int) targetR02.Y, (int) targetR02.X] = 1;
                                ChangeMapArray(targetL01, targetL02);
                            }
                        }
                        else
                        {
                            MoveRole(-1, 0);
                        }
                    }
                    else
                    {
                        
                    }
                    break;
                    case Key.Up:
                      Point targetU01=new Point(rolePosition.X,rolePosition.Y-1); //  目标位置
                    Point targetU02= new Point(rolePosition.X , rolePosition.Y-2);     //目标位置的目标位置
                    if(IsAccessable(targetU01))
                    {
                        //目标区域有箱子放置时
                        if(IsBoxOn(targetU01))
                        {
                            if(IsAccessable(targetU02)&&!IsBoxOn(targetU02))
                            {
                                MoveRole(0, -1);
                                MoveBox(targetU01,0,-1);
                            }
                            else if (mapArray[(int)targetU02.Y, (int)targetU02.X] == 3)
                            {
                                //将目标区域设为可通行区域,并添加可通行图片到画面中
                                MoveRole(0, -1);
                                //       mapArray[(int) targetR02.Y, (int) targetR02.X] = 1;
                                ChangeMapArray(targetU01, targetU02);
                            }
                        }
                        else
                        {
                            MoveRole(0, -1);
                        }
                    }
                    else
                    {
                        
                    }
                  //  rolePosition.Y -= 1;
                    break;
                    case Key.Down:
                      Point targetD01=new Point(rolePosition.X,rolePosition.Y+1); //  目标位置
                    Point targetD02= new Point(rolePosition.X , rolePosition.Y+2);     //目标位置的目标位置
                    if(IsAccessable(targetD01))
                    {
                        //目标区域有箱子放置时
                        if(IsBoxOn(targetD01))
                        {
                            if(IsAccessable(targetD02)&&!IsBoxOn(targetD02))
                            {
                                MoveRole(0,1);
                                MoveBox(targetD01,0,1);
                            }
                            else if (mapArray[(int)targetD02.Y, (int)targetD02.X] == 3)
                            {
                                //将目标区域设为可通行区域,并添加可通行图片到画面中
                                MoveRole(0, 1);
                                //       mapArray[(int) targetR02.Y, (int) targetR02.X] = 1;
                                ChangeMapArray(targetD01, targetD02);
                            }
                        }
                        else
                        {
                            MoveRole(0, 1);
                        }
                    }
                    else
                    {
                        
                    }
                 //   rolePosition.Y += 1;
                    break;
                //    重置本关卡逻辑
                case Key.R:
                    GameStateManagy.StartGame(level);
                    break;

                    case Key.Escape:
                    GameStateManagy.GameExit();
                    break;
                    case Key.System:
                      GameStateManagy.GameExit();
                    break;
            }
        }
        public void GameApp_KeyUp(object sender, KeyEventArgs e)
        {
          //  textBlock1.Text = "捕获按键活动，释放" + e.Key.ToString()+"\n";
        }
        /// <summary>
        /// 根据某一格数返回这一格上是否有箱子放着
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
       private bool IsBoxOn(Point point)
       {
            foreach (Point point1 in boxPosition)
            {
                if (point==point1)
                {
                    return true;
               //     break;
                }
            }
           return false;
       }

        private bool IsAccessable(Point point)
       {
           if (point.Y >= 0 && point.Y <= maxHeight-1 && point.X <= maxWidth-1 && point.X>=0)
           if (mapArray[(int)point.Y, (int)point.X] == 1&&(point.X>=0&&point.X<=maxWidth&&point.Y>=0&&point.Y<=maxHeight))
               return true;
           else
               return false;
           return false;
       }
        /// <summary>
        /// 移动某个位置上的箱子
        /// </summary>
        /// <param name="point">指定位置格子</param>
        /// <param name="x">移动的X方向位置数目</param>
        /// <param name="y">移动的 Y方向位置数目</param>
        private void MoveBox(Point point,int x,int y)
        {
            for (int i = 0; i < boxPosition.Count(); i++)
            {
                
                if (point == boxPosition[i])
                {
                    if (boxPosition[i].X + x <= maxWidth && boxPosition[i].Y + y < maxHeight && boxPosition[i].X + x >= 0 && boxPosition[i].Y + y>=0)
                    {
                        boxPosition[i] = new Point(boxPosition[i].X + x, boxPosition[i].Y + y);
                   //     boxPosition[i].X = boxPosition[i].X + x;
                     //   boxPosition[i].Y += y;
                    } 
                    break;
                }
            }
            
        }
        private void MoveRole(int x,int y)
        {
            if(rolePosition.X+x>=0&&rolePosition.X+x<=maxWidth&&rolePosition.Y+y<=maxHeight&&rolePosition.Y+y>=0)
            {
                rolePosition.X += x;
                rolePosition.Y += y;
                stepCount += 1;
            }
        }
        private bool CheckComplete()
        {
            for (int i = 0; i < targetPosition.Count(); i++)
            {
                if (!IsBoxOn(targetPosition[i]))
                {
                    return false;
                   // break;
                }
            }
            return true;
        }
        private void ChangeMapArray(Point BoxPosition,Point riverPosition)
        {
            mapArray[(int)riverPosition.Y, (int)riverPosition.X] = 1;
            Image image = new Image();
            image.Source = images[0];
            image.Width = defaultWidth;
            image.Height = defaultHeight;
            image.RenderTransform = new TranslateTransform()
            {
                X = riverPosition.X * defaultWidth + defaultPosition.X,
                Y = riverPosition.Y * defaultHeight + defaultPosition.Y
            };
            mainArea.Children.Add(image);
            Canvas.SetZIndex(image,3);
         //   Repaint();

            //  mainArea.Children.Remove(mainRole);
          // mainArea.Children.Add(mainRole);
            for (int i = 0; i < boxPosition.Count(); i++)
            {
                if (BoxPosition == boxPosition[i])
                {
boxPosition.RemoveAt(i);
                    mainArea.Children.Remove(boxImages[i]);
                    boxImages.RemoveAt(i);
                    break;
                }
            }
        }
    }
}
